﻿
namespace MIAPWEB.Forms
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.UI.WebControls;
    using Intellego.Web.ValidationEngine;
    using MIAP.Entidades;
    using MIAP.Negocio;
    using MIAPWEB.Common;

    /// <summary>
    /// Clase de la vista AdministracionUsuario.
    /// </summary>
    public partial class AltaPerfilesUsuario : PageBase
    {
        #region Constantes

        /// <summary>
        /// Almacena el nombre del perfil Administrador.
        /// </summary>
        public const string ADMINISTRADOR = "Administrador";

        #endregion

        #region Campos

        /// <summary>
        /// Clase de negocio para las operaciones de usuarios.
        /// </summary>
        private AdministrarUsuariosNegocio usuarioNegocio;

        /// <summary>
        /// Clase de negocio para las operaciones de alta de usuarios.
        /// </summary>
        private AltaUsuariosNegocio altaUsuarioNegocio;

        /// <summary>
        /// Clase de negocio para las operaciones de alta de usuariosPerfiles.
        /// </summary>
        private AltaUsuariosPerfilesNegocio altaUsuarioPerfilesNegocio;

        /// <summary>
        /// Clase de negocio de las operaciones de perfiles.
        /// </summary>
        private AdministrarPerfilesNegocio perfilesNegocio;

        /// <summary>
        /// Clase de negocio de las operaciones de proyecto.
        /// </summary>
        private AdministrarProyectosNegocio proyectoNegocio;

        /// <summary>
        /// Clase de negocio para las operaciondes de configuración.
        /// </summary>
        private ConfiguracionNegocio configuracionNegocio;

        /// <summary>
        /// Clase de negocio para las operaciones comunes del sistema.
        /// </summary>
        private ComunesNegocio comunesNegocio;

        /// <summary>
        /// Almacena la información del usuario que será guardado.
        /// </summary>
        UsuarioInfo usuario;       

        #endregion

        #region Propiedades

        /// <summary>
        /// Obtiene o establece el id del usuario.
        /// </summary>
        public int IdUsuario
        {
            get
            {
                return (int)this.ViewState["IdUsuario"];
            }

            set
            {
                this.ViewState["IdUsuario"] = value;
            }
        }

        /// <summary>
        /// Obtiene o establece el id del perfil del usuario.
        /// </summary>
        public int IdPerfil
        {
            get
            {
                return (int)this.ViewState["IdPerfil"];
            }

            set
            {
                this.ViewState["IdPerfil"] = value;
            }
        }

        /// <summary>
        /// Obtiene o establece el modo de la vista.
        /// </summary>
        public bool EsModificacion
        {
            get
            {
                return (bool)this.ViewState["EsModificacion"];
            }

            set
            {
                this.ViewState["EsModificacion"] = value;
            }
        }

        /// <summary>
        ///  Obtiene o establece la lista de usuarios que no han sido dados de alta en el sistema.
        /// </summary>
        private List<UsuarioInfo> ListUsuario
        {
            get
            {
                return (List<UsuarioInfo>) this.ViewState["ListUsuario"];
            }

            set
            {
                this.ViewState["ListUsuario"] = value;
            }
        }

        /// <summary>
        /// Obtiene o establecelos archivos que serán guardados.
        /// </summary>
        public List<ArchivoInfo> ListArchivos
        {
            get
            {
                return (List<ArchivoInfo>)this.ViewState["ListArchivos"];
            }

            set
            {
                this.ViewState["ListArchivos"] = value;
            }
        }       

        /// <summary>
        /// Obtiene o establece el id del Perfil Administrador.
        /// </summary>
        private CatalogoInfo Catalog
        {
            get
            {
                return (CatalogoInfo)this.ViewState["Catalog"];
            }

            set
            {
                this.ViewState["Catalog"] = value;
            }
        }

        #endregion

        #region Constructor

        public AltaPerfilesUsuario()
        {
            this.usuarioNegocio = new AdministrarUsuariosNegocio();
            this.altaUsuarioNegocio = new AltaUsuariosNegocio();           
            this.perfilesNegocio = new AdministrarPerfilesNegocio();
            this.altaUsuarioPerfilesNegocio = new AltaUsuariosPerfilesNegocio();
            this.proyectoNegocio = new AdministrarProyectosNegocio();
            this.configuracionNegocio = new ConfiguracionNegocio();
            this.comunesNegocio = new ComunesNegocio();
            this.usuario = new UsuarioInfo();
            this.ListArchivos = new List<ArchivoInfo>();
        }

        #endregion

        #region Eventos

        /// <summary>
        /// Evento que se ejecuta al cargar la página.
        /// </summary>
        /// <param name="sender">Objeto que invoca al evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            this.InitValidation();

            this.grdArchivosCargar.PageSize = Convert.ToInt32(new ConfiguracionNegocio().GetNumeroPaginasGrid().Descripcion);

            if (!IsPostBack)
            {
                this.Catalog = this.configuracionNegocio.GetConfiguracionPerfilAdministrador();

                if (Request.UrlReferrer != null)
                {
                    this.PreviousPage = Request.UrlReferrer.ToString();
                }

                this.GetUsuarios();
                this.GetProyectos();                

                // Evaluar que el IdUsuario este contenido en el QueryString.
                if (this.Request.QueryString[AppQueryStrings.IdUsuario] != null)
                {
                    // Obtener el id del usuario.
                    this.IdUsuario = int.Parse(this.Request.QueryString[AppQueryStrings.IdUsuario]);

                    this.IdPerfil = int.Parse(this.Request.QueryString[AppQueryStrings.IdPerfil]);

                    this.ddlUsuario.Visible = false;

                    this.EsModificacion = true;

                    this.LoadUsuario();

                    this.ddlUsuario.Enabled = false;
                    this.ddlPerfil.Enabled = false;                    
                    this.ddlProyecto.Enabled = false;
                    this.lblTitulo.Text = this.GetGlobalResourceObject("Strings", "lblTituloEdicionPerfilesUsuario").ToString();
                }
                else 
                {
                    this.lblTitulo.Text = this.GetGlobalResourceObject("Strings", "lblTituloAltaPerfilesUsuario").ToString();
                    this.EsModificacion = false;
                    this.IdUsuario = 0;
                }
            }
        }

        /// <summary>
        /// Método ejecutado al dar click al botón guardar.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void btnGuardar_Click(object sender, EventArgs e)
        {
            if (this.ListArchivos.Count == default(int))
            {
                this.ShowMessage(this.GetGlobalResourceObject("Strings", "AltaPerfilUsuario_NoExistenArchivosAsociados").ToString());
            }
            else
            {
                this.SetUsuario();

                if (!EsModificacion)
                {
                    // Verificar que el perfil no se encuentre asociado al usuario.
                    bool existencia = this.altaUsuarioPerfilesNegocio.VerifyExistencePerfilUsuario(this.usuario.IdUsuario, usuario.IdPerfil);

                    if (!existencia)
                    {
                        this.altaUsuarioPerfilesNegocio.AddPerfilUsuario(usuario, ListArchivos, AppSessionManager.Instance.Usuario);
                        this.ShowMessage(this.GetGlobalResourceObject("Strings", "AltPerfilesUsuario_PerfilAgregado").ToString());                        
                    }
                    else
                    {
                        this.ShowMessage(this.GetGlobalResourceObject("Strings", "AltaPerfilesUsuario_PerfilYaRelacionado").ToString());
                    }
                    
                }
                else
                {
                    this.altaUsuarioPerfilesNegocio.EditPerfilUsuario(usuario, ListArchivos, AppSessionManager.Instance.Usuario);
                    this.ShowMessage(this.GetGlobalResourceObject("Strings", "AltaPerfilesUsuario_PerfilEditado").ToString(), this.PreviousPage);
                }

                this.Clean();
            }
        }

        /// <summary>
        /// Método ejecutado al dar click al botón Salir. Redirecciona a la última página visitada.
        /// </summary>
        /// <param name="sender">Objeto que invoca al evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void btnSalir_Click(object sender, EventArgs e)
        {
            Response.Redirect(this.PreviousPage);
        }

        /// <summary>
        /// Método ejecutado al cambiar la selección del dropdownlist del usuario. Obtiene a información del área y subarea a la que pertenece el usuario seleccionado.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        public void ddlUsuario_SelectedIndexChanged(object sender, EventArgs e)
        {
            DropDownList dropUsuario = (DropDownList)sender;

            int idUsuario = int.Parse(dropUsuario.SelectedValue);

            if (idUsuario > default(int))
            {
                UsuarioInfo usuario = this.ListUsuario.Where(p => p.IdUsuario == idUsuario).Single();
                this.lblNombre.Text = usuario.NombreCompleto;
                this.lblArea.Text = usuario.Area;
                this.lblSubarea.Text = usuario.SubArea;
                this.lblEstatus.Text = this.GetGlobalResourceObject("strings", "Activo").ToString();
            }
            else
            {
                this.lblNombre.Text = string.Empty;
                this.lblArea.Text = string.Empty;
                this.lblSubarea.Text = string.Empty;
                this.lblEstatus.Text = string.Empty;
            }
        }

        /// <summary>
        /// Método ejecutado al cambiar la seleción del dropdownlist de proyectos. Obtiene los archivos relacionados a un proyecto.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void ddlProyecto_SelectedIndexChanged(object sender, EventArgs e)
        {
            DropDownList dropProyecto = (DropDownList)sender;

            int idProyecto = int.Parse(dropProyecto.SelectedValue);

            this.GetPerfiles(idProyecto);

            this.GetArchivosByProyecto(idProyecto);
        }

        /// <summary>
        /// Evento que se ejecuta cuando se cambia de página en el grid.
        /// </summary>
        /// <param name="sender">Objeto que invoca el evento.</param>
        /// <param name="e">Argumentos del evento.</param>
        protected void grdArchivosCargar_OnPageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            this.SetArchivosByUsuario();
            this.grdArchivosCargar.PageIndex = e.NewPageIndex;
            this.grdArchivosCargar.DataSource = this.ListArchivos;
            this.grdArchivosCargar.DataBind();
        }

        #endregion

        #region Métodos

        /// <summary>
        /// Obtiene todos los usuarios que aún no han sido dados de elta en el sistema.
        /// </summary>
        private void GetUsuarios()
        {
            this.ListUsuario = this.usuarioNegocio.GetSingleUsuarios(new UsuarioInfo());

            this.ddlUsuario.DataSource = this.ListUsuario;
            this.ddlUsuario.DataBind();
            this.comunesNegocio.SetSeleccionar(this.GetGlobalResourceObject("strings", "Seleccionar").ToString(), this.ddlUsuario);
        }

        /// <summary>
        /// Obtiene todos los proyectos.
        /// </summary>
        private void GetProyectos()
        {
            this.ddlProyecto.DataSource = this.proyectoNegocio.GetCatalogProyecto();
            this.ddlProyecto.DataBind();
            this.comunesNegocio.SetSeleccionar(this.GetGlobalResourceObject("strings", "Seleccionar").ToString(), this.ddlProyecto);
        }

        /// <summary>
        /// Obtiene todos los perfiles.
        /// </summary>
        private void GetPerfiles(int? idProyecto)
        {
            List<CatalogoInfo> listPerfiles = this.perfilesNegocio.GetCatalogPerfiles(idProyecto);

            if (idProyecto > default(int))
            {
                listPerfiles.Add(new CatalogoInfo() { IdItem = int.Parse(this.Catalog.Descripcion), Descripcion = ADMINISTRADOR });
            }

            listPerfiles = listPerfiles.OrderBy(p => p.Descripcion).ToList();

            this.ddlPerfil.DataSource = listPerfiles;
            this.ddlPerfil.DataBind();
            this.comunesNegocio.SetSeleccionar(this.GetGlobalResourceObject("strings", "Seleccionar").ToString(), this.ddlPerfil);
        }      

        /// <summary>
        /// Obtiene todos los archivos relacionados a un proyecto.
        /// </summary>
        /// <param name="idProyecto">Id de proyecto.</param>
        private void GetArchivosByProyecto(int idProyecto)
        {
            this.ListArchivos = this.altaUsuarioPerfilesNegocio.GetArchivosByIdProyecto(idProyecto);
            this.grdArchivosCargar.DataSource = this.ListArchivos;
            this.grdArchivosCargar.DataBind(); 
        }

        /// <summary>
        /// Establece la información que ha de ser guardada.
        /// </summary>
        private void SetUsuario()
        {
            // Se trata de una modificación.
            if (EsModificacion)
            {
                this.usuario.IdUsuario = IdUsuario;
                this.usuario.IdProyecto = int.Parse(this.ddlProyecto.SelectedValue) <= default(int) ? this.usuario.IdProyecto = null : int.Parse(this.ddlProyecto.SelectedValue);
            }
            else
            {
                this.usuario.IdUsuario = int.Parse(this.ddlUsuario.SelectedValue);
            }
            
            this.usuario.IdPerfil = int.Parse(ddlPerfil.SelectedValue);

            // Si el perfil es diferente al perfil de Admnistrador.
            if (ddlPerfil.SelectedValue != Catalog.Descripcion)
            {
                this.usuario.PuedeEjecutarProyecto = null;//this.chkEjecutaProyecto.Checked;
            }
            else
            {
                this.usuario.PuedeEjecutarProyecto = null;
            }

            SetArchivosByUsuario();
        }

        /// <summary>
        /// Carga toda la información del usuario.
        /// </summary>
        private void LoadUsuario()
        {
            // Obtener el usuario.                    
            this.usuario = this.altaUsuarioPerfilesNegocio.GetUsuarioPerfilById(this.IdUsuario, this.IdPerfil);
            this.LoadArchivosByUsuario();

            this.lblUsuario.Text = usuario.AliasUsuario;
            this.lblNombre.Text = usuario.NombreCompleto;
            this.lblArea.Text = usuario.Area;
            this.lblSubarea.Text = usuario.SubArea;
            this.lblEstatus.Text = usuario.Estatus;

            this.ddlProyecto.SelectedValue = this.usuario.IdProyecto.ToString();

            if (this.usuario.IdProyecto != null)
            {
                // Obtener los perfiles para el proyecto.
                this.GetPerfiles(usuario.IdProyecto.Value);
            }
            else
            {
                this.GetPerfiles(null);
            }

            this.ddlPerfil.SelectedValue = this.IdPerfil.ToString();
        }

        /// <summary>
        /// Carga los archivos relacionados con el usuario.
        /// </summary>
        private void LoadArchivosByUsuario()
        {
            if (this.usuario.IdProyecto != null)
            {
                this.ListArchivos = this.altaUsuarioPerfilesNegocio.GetArchivosByUsuario(this.IdUsuario, usuario.IdProyecto.Value);
            }
            else
            {
                this.ListArchivos = this.altaUsuarioPerfilesNegocio.GetArchivosByUsuario(this.IdUsuario, null);
            }

            this.grdArchivosCargar.DataSource = this.ListArchivos;
            this.grdArchivosCargar.DataBind();

            this.GetArchivosByUsuario();
        }

        /// <summary>
        /// Obtiene los archivos asociados al usuario.
        /// </summary>
        /// <returns>List<PermisoInfo></returns>
        private void GetArchivosByUsuario()
        {
            foreach (GridViewRow row in grdArchivosCargar.Rows)
            {
                int idArchivo = int.Parse(grdArchivosCargar.DataKeys[row.RowIndex].Value.ToString());

                ArchivoInfo archivo = ListArchivos.Where(p => p.IdentificadorArchivo == idArchivo).Single();

                CheckBox checkCargar = row.FindControl("chkCargarArchivo") as CheckBox;
                CheckBox checkAutorizar = row.FindControl("chkAutorizarArchivo") as CheckBox;

                checkCargar.Checked = archivo.PuedeCargarArchivo;
                checkAutorizar.Checked = archivo.PuedeAutorizarRecarga;
            }
        }

        /// <summary>
        /// Obtiene los permisos asociados al perfil
        /// </summary>
        /// <returns>List<PermisoInfo></returns>
        private void SetArchivosByUsuario()
        {
            foreach (GridViewRow row in grdArchivosCargar.Rows)
            {
                var checkCargarArchivo = row.FindControl("chkCargarArchivo") as CheckBox;
                var checkAutorizarArchivo = row.FindControl("chkAutorizarArchivo") as CheckBox;
                int id = int.Parse(grdArchivosCargar.DataKeys[row.RowIndex].Value.ToString());

                this.ListArchivos.Single(elemento => elemento.IdentificadorArchivo == id).PuedeCargarArchivo = checkCargarArchivo.Checked;
                this.ListArchivos.Single(elemento => elemento.IdentificadorArchivo == id).PuedeAutorizarRecarga = checkAutorizarArchivo.Checked;
            }
        }     
        
        /// <summary>
        /// Agregar las validaciones para los campos requeridos.
        /// </summary>
        private void InitValidation()
        {
            ValidationRule ruleIdUsuario = new ValidationRule(this.ddlUsuario);
            ValidationRule ruleIdPerfil = new ValidationRule(this.ddlPerfil);

            ruleIdUsuario.NotEmpty(this.GetGlobalResourceObject("strings", "ErrorDropDownRequerido").ToString()); 
            ruleIdPerfil.NotEmpty(this.GetGlobalResourceObject("strings", "ErrorDropDownRequerido").ToString());

            this.ValidationEngine.Add(ruleIdUsuario);
            this.ValidationEngine.Add(ruleIdPerfil);
        }

        /// <summary>
        /// Limpia los controles.
        /// </summary>
        public void Clean()
        {
            this.ddlUsuario.SelectedIndex = -1;
            this.ddlProyecto.SelectedIndex = -1;            
            this.ddlPerfil.SelectedIndex = -1;
            this.GetArchivosByProyecto(int.Parse(ddlProyecto.SelectedValue));
        }

        #endregion     
    }
}